/**
 * 
 */
package edu.gatech.cs3240.NFA;

import edu.gatech.cs3240.Token;
import edu.gatech.cs3240.NFA.NFA.InvalidNFATraversalException;

/**
 * A transition between two states in an NFA.
 * @author VRamachandran
 */
public class Transition {
	
	private State target;
	private State source;
	private Token consume;
	private boolean epsilon = true;
	
	/**
	 * Can I traverse this transition without consuming anything?
	 * @return
	 */
	public boolean isEpsilon() {
		return epsilon;
	}
	
	public State getTarget() {
		return target;
	}
	
	public State getSource() {
		return source;
	}
	
	public boolean equals(Object o) {
		 return ((o instanceof Transition) && 
				(((Transition) o).getSource() == source) &&
				(((Transition) o).getTarget() == target) &&
				(epsilon ? ((Transition) o).isEpsilon() : 
					!(consume == ((Transition) o).getConsumable())));
	}
	
	/**
	 * Pulls off the consumed character from the front of the string, and
	 * returns the remaining string.
	 * @param s The string to process
	 * @return The input string with the consumed character removed.
	 * @throws InvalidNFATraversalException If the token to be consumed at this
	 * transition is not at the front of the string.  This should have been
	 * caught before attempting to traverse.
	 */
	public String consume(String s) throws InvalidNFATraversalException {
		if(epsilon)
			return s;
		else if(s.startsWith(consume.toString()))
			return s.substring(1);
		else throw new InvalidNFATraversalException(consume.toString());
	}
	
	public Token getConsumable() {
		return consume;
	}
	
	public Transition(State source, State target, Token consume) {
		this(source, target);
		this.consume = consume;
		epsilon = false;
	}
	
	public Transition(State source, State target) {
		this.source = source;
		this.target = target;
	}
}